from abc import ABC, abstractmethod
from typing import Optional, List, Any, Dict
import pandas as pd
from datetime import datetime


class AbstractDatabase(ABC):
    """抽象数据库基类，定义数据库操作的接口"""

    @abstractmethod
    def connect(self) -> bool:
        """
        建立数据库连接
        
        Returns:
            bool: 连接是否成功
        """
        pass

    @abstractmethod
    def disconnect(self) -> None:
        """关闭数据库连接"""
        pass

    @abstractmethod
    def save_data(
            self,
            table_name: str,
            data: pd.DataFrame,
            if_exists: str = 'append',
            index_elements: Optional[List[str]] = None
    ) -> bool:
        """
        保存DataFrame数据到数据库
        
        Args:
            table_name: 目标表名
            data: 要保存的DataFrame数据
            if_exists: 如果表存在时的处理方式 ('fail', 'replace', 'append')
            index_elements: 用于处理冲突的索引列名列表
            
        Returns:
            bool: 保存是否成功
        """
        pass

    @abstractmethod
    def query_data(
            self,
            table_name: str,
            conditions: Optional[Dict[str, Any]] = None,
            start_date: Optional[datetime] = None,
            end_date: Optional[datetime] = None,
            date_column: str = 'trade_date',
            columns: Optional[List[str]] = None,
            order_by: Optional[List[str]] = None
    ) -> pd.DataFrame:
        """
        从数据库查询数据
        
        Args:
            table_name: 表名
            conditions: 查询条件字典，如 {'ts_code': '000001.SZ'}
            start_date: 开始日期
            end_date: 结束日期
            date_column: 日期列名
            columns: 要查询的列名列表
            order_by: 排序列名列表
            
        Returns:
            pd.DataFrame: 查询结果
        """
        pass

    @abstractmethod
    def execute_query(self, query: str, params: Optional[Dict[str, Any]] = None) -> Any:
        """
        执行原始SQL查询
        
        Args:
            query: SQL查询语句
            params: 查询参数字典
            
        Returns:
            Any: 查询结果
        """
        pass
